<script setup lang="ts">
import {User, View, QuestionFilled, Share, ChatDotRound, Document} from '@element-plus/icons-vue'
import {onMounted, ref, nextTick} from "vue";
import {getTopInfoList, getWeekVisitCharts, getPhyInfo} from "@/api/dashboard.ts";
import * as echarts from 'echarts'

interface topInfo {
  color: string;
  icon: any;
  value: number;
  label: string;
}

interface DiskInfo {
  name: string;
  total: number;
  used: number;
  free: number;
}

const stats = ref<topInfo[]>([])
const weekChartRef = ref()
const weekChartData = ref({ days: [], counts: [] })
const memoryChartRef = ref()
const diskChartRef = ref()
const phyInfo = ref<{ memory: { total: number; used: number; free: number }; disks: DiskInfo[] }>({ memory: { total: 0, used: 0, free: 0 }, disks: [] })

const findTopList = async () => {
  let res = await getTopInfoList();
  if (res.code === 200) {
    if (res.data) {
      stats.value = res.data;
    } else {
      stats.value = [
        {color: '#409EFF', icon: User, value: 803, label: '新用户'},
        {color: '#13ce66', icon: View, value: 232, label: '累计点击'},
        {color: '#ffba00', icon: QuestionFilled, value: 142, label: '新增问答'},
        {color: '#ff4d4f', icon: Share, value: 657, label: '分享统计'},
        {color: '#e15b99', icon: ChatDotRound, value: 12, label: '新增互动'},
        {color: '#a084e8', icon: Document, value: 14, label: '新增页面'}
      ]
    }
  }
}

const loadWeekChart = async () => {
  const res = await getWeekVisitCharts()
  if (res.code === 200 && res.data) {
    weekChartData.value = res.data
    await nextTick(() => {
      renderWeekChart()
    })
  }
}

const renderWeekChart = () => {
  if (!weekChartRef.value) return
  const chart = echarts.init(weekChartRef.value)
  chart.setOption({
    title: { text: '近一周访问记录', left: 'center' },
    tooltip: { trigger: 'axis' },
    xAxis: { type: 'category', data: weekChartData.value.days },
    yAxis: { type: 'value' },
    series: [{
      data: weekChartData.value.counts,
      type: 'line',
      smooth: true,
      areaStyle: {}
    }]
  })
}

const loadPhyInfo = async () => {
  const res = await getPhyInfo()
  if (res.code === 200 && res.data) {
    phyInfo.value = res.data
    await nextTick(() => {
      renderMemoryChart()
      renderDiskChart()
    })
  }
}

function formatGB(val: number) {
  return (val / 1024 / 1024 / 1024).toFixed(2) + ' GB'
}

const renderMemoryChart = () => {
  if (!memoryChartRef.value) return
  const { total, used, free } = phyInfo.value.memory
  const chart = echarts.init(memoryChartRef.value)
  chart.setOption({
    title: { text: '内存使用情况', left: 'center', top: 10, textStyle: { fontSize: 18 } },
    tooltip: {
      trigger: 'item',
      backgroundColor: '#fff',
      borderColor: '#eee',
      borderWidth: 1,
      textStyle: { color: '#333' },
      formatter: (params: any) => `${params.name}: ${formatGB(params.value)} (${params.percent}%)`
    },
    legend: { bottom: 0, left: 'center' },
    series: [{
      name: '内存',
      type: 'pie',
      radius: ['50%', '70%'],
      avoidLabelOverlap: false,
      label: {
        show: true,
        position: 'center',
        formatter: (params: any) => `总计\n${formatGB(total)}`,
        fontSize: 16,
        color: '#666',
        fontWeight: 'bold'
      },
      emphasis: { label: { show: true, fontSize: 18, fontWeight: 'bold' } },
      labelLine: { show: false },
      data: [
        { value: used, name: '已用' },
        { value: free, name: '空闲' }
      ]
    }]
  })
}

const renderDiskChart = () => {
  if (!diskChartRef.value) return
  const disks = phyInfo.value.disks || []
  const names = disks.map((d: DiskInfo) => d.name)
  const used = disks.map((d: DiskInfo) => d.used)
  const free = disks.map((d: DiskInfo) => d.free)
  const total = disks.map((d: DiskInfo) => d.total)
  const chart = echarts.init(diskChartRef.value)
  chart.setOption({
    title: { text: '硬盘存储信息', left: 'center', top: 10, textStyle: { fontSize: 18 } },
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      backgroundColor: '#fff',
      borderColor: '#eee',
      borderWidth: 1,
      textStyle: { color: '#333' },
      formatter: (params: any) => {
        let str = params[0].name + '<br/>';
        params.forEach((item: any) => {
          str += `${item.marker}${item.seriesName}: ${formatGB(item.value)}<br/>`
        });
        return str;
      }
    },
    legend: { bottom: 0, left: 'center', data: ['已用', '空闲'] },
    grid: { left: '3%', right: '4%', bottom: '10%', containLabel: true },
    xAxis: {
      type: 'value',
      max: (value: { max: number }) => value.max * 1.2,
      axisLabel: { formatter: (v: number) => formatGB(v) },
      splitLine: { show: true, lineStyle: { color: '#f0f0f0' } }
    },
    yAxis: { type: 'category', data: names },
    series: [
      {
        name: '已用',
        type: 'bar',
        stack: 'total',
        label: {
          show: true,
          position: 'inside',
          formatter: (params: any) => formatGB(params.value),
          fontSize: 12
        },
        itemStyle: { color: '#409EFF' },
        data: used
      },
      {
        name: '空闲',
        type: 'bar',
        stack: 'total',
        label: {
          show: true,
          position: 'inside',
          formatter: (params: any) => formatGB(params.value),
          fontSize: 12
        },
        itemStyle: { color: '#67C23A' },
        data: free
      }
    ]
  })
}

onMounted(async () => {
  await findTopList()
  await loadWeekChart()
  await loadPhyInfo()
})
</script>

<template>
  <div>
  <el-row :gutter="20">
    <el-col :span="4" v-for="item in stats" :key="item.label">
      <el-card class="stat-card">
        <div class="card-content">
          <div class="icon-block" :style="{ background: item.color }">
            <el-icon :size="32">
              <component :is="item.icon"/>
            </el-icon>
          </div>
          <div class="info-block">
            <div class="stat-value">{{ item.value }}</div>
            <div class="stat-label">{{ item.label }}</div>
          </div>
        </div>
      </el-card>
    </el-col>
  </el-row>
  <el-row :gutter="20" style="margin-top: 32px;">
    <el-col :span="12">
      <div ref="memoryChartRef" style="width: 100%; height: 320px; background: #fff; border-radius: 8px; box-shadow: 0 2px 8px 0 rgba(44, 62, 80, 0.08);"></div>
    </el-col>
    <el-col :span="12">
      <div ref="diskChartRef" style="width: 100%; height: 320px; background: #fff; border-radius: 8px; box-shadow: 0 2px 8px 0 rgba(44, 62, 80, 0.08);"></div>
    </el-col>
  </el-row>
  <div ref="weekChartRef" style="width: 100%; height: 400px; margin-top: 32px; background: #fff; border-radius: 8px; box-shadow: 0 2px 8px 0 rgba(44, 62, 80, 0.08);"></div>
  </div>
</template>

<style scoped>
.stat-card {
  padding: 0;
  border-radius: 8px;
  box-shadow: 0 2px 8px 0 rgba(44, 62, 80, 0.08);
}

.card-content {
  display: flex;
  align-items: center;
  height: 80px;
}

.icon-block {
  width: 60px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-top-left-radius: 8px;
  border-bottom-left-radius: 8px;
  color: #fff;
  font-size: 32px;
}

.info-block {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  padding-left: 16px;
}

.stat-value {
  font-size: 32px;
  font-weight: bold;
  color: #444;
}

.stat-label {
  font-size: 14px;
  color: #888;
  margin-top: 4px;
}
</style>
